home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / mstrenv.zip / MSTR_ENV.H < prev   
Text File  |  1993-01-04  |  10KB  |  290 lines

  1.  
  2. /**********************************************************************/
  3. /*                                                                    */
  4. /* mstr_env.h MS 'C' ver. to get/put DOS master environment variables */
  5. /*                                                                    */
  6. /* Purpose:   Functions to deal with the DOS master (not local) envir-*/
  7. /*            onment. Ordinary getenv and putenv functions deal with  */
  8. /*            the local environment; that can NOT be accessed from    */
  9. /*            the DOS command line and batch files. This routine      */
  10. /*            finds, reads, and writes to the master environment.     */
  11. /*                                                                    */
  12. /* Author:    Scott Ladd, 302 N 12th Street,                          */
  13. /*            Gunnison, Colorado, 81230.                              */
  14. /*                                                                    */
  15. /* Published: The C Users Journal, July, 1989, pages 59ff.            */
  16. /*                                                                    */
  17. /* Modified:  T. E. McCormick, 06/89, for Microsoft C use only.       */
  18. /*            Refer to the article mentioned above for additional     */
  19. /*            details, Turbo C capability, etc. The changes are few.  */
  20. /*            but many comments were left out since I was keying it   */
  21. /*            in from the magazine!                                   */
  22. /*                                                                    */
  23. /**********************************************************************/
  24.  
  25.  
  26. /**************** Global declarations  ********************************/
  27. char far *      env_ptr;           /* pointer: 1st byte global envir. */
  28. static unsigned env_length;        /* length of global environment.   */
  29. static int      initialized = 0;   /* tells if module was initialized.*/
  30. static char     s[256];            /* internal buffer for strings.    */
  31. static void     m_findenv(void);   /* function to find master envir.  */
  32. #define NUL '\x00'                 /* null char is string terminator. */
  33. int  env_len;                      /* length of global envir string   */
  34.  
  35.  
  36. /**************** Beginning of Microsoft-dependent code. **************/
  37. /***  Sorry about removing the `if defined`s, but I was keying this ***/
  38. /***  from the printed magazine article. I have omitted many useful ***/
  39. /***  comments and the function headings documentation. Please refer **/
  40. /***  to the July, 1989 C Users Journal available from the C Users  ***/
  41. /***  Group, 2120 W 25th Street, Suite B, Lawrence KS 66046-9972.   ***/
  42. /**********************************************************************/
  43.  
  44.  
  45. /* Following macro must be generated for Microsoft C and Quick C.     */
  46. /* It will make a far pointer. Borland Turbo C provides MK_FP.        */
  47. /* This MK-FP function was modified from the published version.       */
  48.  
  49. /****** MK_FP make far pointer function: see Borland TC dos.h file. ***/
  50. #define MK_FP(seg,ofs)  ((void far *) \
  51.                            (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
  52.  
  53. /****** poke and peek are humble attempts to emulate BASIC functions. */
  54. #define poke(a,b,c)     (*((int  far*)MK_FP((a),(b))) = (int)(c))
  55. #define pokeb(a,b,c)    (*((char far*)MK_FP((a),(b))) = (char)(c))
  56. #define peek(a,b)       (*((int  far*)MK_FP((a),(b))))
  57. #define peekb(a,b)      (*((char far*)MK_FP((a),(b))))
  58.  
  59.  
  60. typedef struct
  61.    {
  62.    char reserved1[22];
  63.    unsigned par_seg;       /* set of parent of current program */
  64.    char reserved2[20];
  65.    unsigned env_seg;       /* environment seg: current program */
  66.    }
  67.    PSP;
  68. /* Following pragma also required for Microsoft C and Quick C.        */
  69. /* It is essential to compile the MCB with byte, not word alignment.  */
  70. /* Borland Turbo C uses byte alignment, it must be forced with MSC.   */
  71.    #pragma pack(1) 
  72. /****************       End of Microsoft-dependent code. **************/
  73.  
  74. typedef struct
  75.    {
  76.    char status;        /* indicates if this block is in chain         */
  77.    unsigned owner_psp; /* psp segment of this block`s owner.          */
  78.    unsigned len;       /* size in paragraphs of this memory block.    */
  79.    }
  80.    MCB;
  81.  
  82. /**************** Beginning of Microsoft-dependent code. **************/
  83.    #pragma pack()
  84. /****************       End of Microsoft-dependent code. **************/
  85.  
  86.  
  87. /**************** Function declaration:                  **************/
  88.         char * m_getenv(char * name)
  89.            {
  90.    char far * e;
  91.    char *     n;
  92.    int        i;
  93.  
  94.    if (!initialized)               /* initialize if needed            */
  95.       m_findenv();
  96.    e = env_ptr;
  97.  
  98.    while (*e)                      /* search for name                 */
  99.        {
  100.        n = name;
  101.  
  102.        while ((*e == *n) && (*e != '=') && (*e != NUL) && (*n != NUL))
  103.            {
  104.            ++e;
  105.            ++n;
  106.            }
  107.  
  108.        if ((*n == NUL) && (*e == '='))    /* means we found name.     */
  109.            {
  110.            ++e;
  111.  
  112.            /***** strcpy() can`t be used: pointer sizes may differ ****/
  113.            for (i = 0; (i < 256) && (*e != NUL); ++i)
  114.                {
  115.                s[i] = *e;
  116.                ++e;
  117.                }
  118.  
  119.            if (i < 256)
  120.                s[i] = NUL;
  121.  
  122.            return s;                         /* contains value of name */
  123.            }
  124.  
  125.            /***** skip to the next environment variable            ****/
  126.            while (*e != NUL)
  127.                ++e;
  128.  
  129.            ++e;
  130.            }
  131.  
  132.        return NULL;                           /* name was not found   */
  133.        }
  134.  
  135.  
  136.  
  137. /**************** Function declaration: m_putenv()       **************/
  138. int m_putenv(char *name, char *text)
  139.    {
  140.    char far * e;
  141.    unsigned   l = 0;
  142.    char *     sptr;
  143.  
  144.    if (!initialized)
  145.        m_findenv();
  146.  
  147.    e = env_ptr;
  148.  
  149.    /***** check to insure storage reqd is less than 256 bytes    *******/
  150.    if ((strlen(name) + 2 + strlen(text)) > 256)
  151.        return 1;
  152.  
  153.    /***** make a complete environment string from components given *****/
  154.    strcpy(s,name);
  155.                           /* strupr(s);   */
  156.    strcat(s,"=");
  157.    strcat(s,text);
  158.  
  159.    /***** delete any existing variables of the same name           *****/
  160.    m_delenv(name);
  161.  
  162.  
  163.    /***** find the end of current variables marked by two NULLs    *****/
  164.    e = env_ptr;
  165.    l = 0;
  166.    while (!((*e == NUL) && (*(e+1) == NUL)))
  167.        {
  168.        ++e;
  169.        ++l;
  170.        }
  171.  
  172.    l = env_len - l - 1;      /* will new string fit in environment?   */
  173.  
  174.    if (l < strlen(s))
  175.        return 1;             /* return an error if variable won`t fit */
  176.  
  177.    sptr = s;
  178.    ++e;            /* otherwise, copy onto the end of current envir.  */
  179.    while (*sptr != NUL)
  180.        *e++ = *sptr++;
  181.    *e       = NUL;
  182.    *(e + 1) = NUL;
  183.    return 0;                                   /* it worked           */
  184.    }
  185.  
  186.  
  187.  
  188.  
  189.    /**************** Function declaration: m_delenv()    **************/
  190. int m_delenv(char *name)
  191.    {
  192.    char far * e1;      /* used in search: marks begin next variable   */
  193.    char far * e2;      /* marks beginning of the variable             */
  194.    char * n;           /* used in search: name pointer                */
  195.    int searching = 1;  /* flag to indicate search end                 */
  196.  
  197.    if (!initialized)
  198.        m_findenv();
  199.  
  200.    e1 = env_ptr;
  201.  
  202.    /********* Find the beginning of the variable to be deleted. ******/
  203.    while ((*e1 != NUL) & (searching))
  204.        {
  205.        n  = name;
  206.        e2 = e1;
  207.  
  208.        while ((*e1 == *n) && (*e1 != '=') && (*e1 != NUL) && (*n != NUL))
  209.            {
  210.            ++e1;
  211.            ++n;
  212.            }
  213.  
  214.        if ((!*n) && (*e1 == '='))
  215.            searching = 0;   /* var we want was found: turn flag off   */
  216.  
  217.        while (*e1 != NUL)
  218.            ++e1;
  219.        ++e1;
  220.        }
  221.  
  222.    /****** If the name was not found, return with an error.       *****/
  223.    if ((*e1 == NUL) && (searching))
  224.        return 1;
  225.  
  226.    /****** Otherwise, copy remainder of environment over variable *****/
  227.    while (!((*e1 == NUL) && (*(e1+1) == NUL)))
  228.        {
  229.        *e2 = *e1;
  230.        e2++;
  231.        e1++;
  232.        }
  233.  
  234.    *e2       = NUL;
  235.    *(e2 + 1) = NUL;    /* End the environment with double NUL bytes   */
  236.  
  237.    return 0;                                  /* it worked            */
  238.    }
  239.  
  240.  
  241.  
  242.  
  243. /**************** Function declaration: m_findenv()      **************/
  244. static void m_findenv()
  245.    {
  246.    union  REGS  regs;
  247.    struct SREGS sregs;
  248.                               /**** MCBs are Memory Control Blocks ****/
  249.    int far * SEGptr;          /* set to addr of segment of first MCB  */
  250.    MCB far * CONFIGmcb;       /* set to addr of CONFIG`s MCB          */
  251.    MCB far * SHELLmcb;        /* set to addr of COMMAND.COM`s MCB     */
  252.    MCB far * ENVmcb;          /* set to addr of environment`s MCB     */
  253.    PSP far * SHELLpsp;        /* set to addr of COMMAND.COM`s PSP     */
  254.  
  255.    regs.h.ah = 0x52;
  256.    intdosx(®s,®s,&sregs);
  257.  
  258.  
  259.    SEGptr    = MK_FP(sregs.es, regs.x.bx - 2);
  260.  
  261.    CONFIGmcb = MK_FP(*SEGptr,0);
  262.  
  263.    SHELLpsp  = MK_FP(FP_SEG(CONFIGmcb) + CONFIGmcb->len + 2, 0);
  264.  
  265.    if (SHELLpsp->env_seg == 0)
  266.        {
  267.        /***** The environment is in the block AFTER the parent program */
  268.        SHELLmcb = MK_FP(FP_SEG(CONFIGmcb) + CONFIGmcb->len + 1, 0);
  269.        env_ptr  = MK_FP(FP_SEG(SHELLmcb)  + SHELLmcb->len  + 2, 0);
  270.        }
  271.    else
  272.        {
  273.  
  274.     /***** Otherwise, we have a direct pointer to the envir block.  */
  275.    env_ptr = MK_FP(SHELLpsp->env_seg, 0);
  276.    }
  277.  
  278.  
  279. ENVmcb = MK_FP(FP_SEG(env_ptr) -1, 0); /* pointer: envir block MCB  */
  280.  
  281. env_len = ENVmcb->len * 16;            /* calc length of envir.     */
  282. initialized = 1;                       /* set init switch to on     */
  283. }
  284.  
  285. /********************************************************************/
  286.  
  287.                /* set init switch to on     */
  288. }
  289.  
  290. /******************************************************